package com.epfresh.api.helper;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.epfresh.api.R;
import com.epfresh.api.constant.Constant;
import com.epfresh.api.entity.City;
import com.epfresh.api.entity.DocFile;
import com.epfresh.api.entity.RequestEntity;
import com.epfresh.api.entity.RequestEntityMap;
import com.epfresh.api.entity.RequestTag;
import com.epfresh.api.entity.ResponseEntity;
import com.epfresh.api.entity.User;
import com.epfresh.api.entity.VersionNew;
import com.epfresh.api.global.AppActivity;
import com.epfresh.api.global.AppApplication;
import com.epfresh.api.http.DownloadFile;
import com.epfresh.api.http.HttpRequest;
import com.epfresh.api.http.OnRequestListener;
import com.epfresh.api.http.RequestManager;
import com.epfresh.api.http.volley.DefaultRetryPolicy;
import com.epfresh.api.http.volley.RetryPolicy;
import com.epfresh.api.update.Constants;
import com.epfresh.api.update.DownloadService;
import com.epfresh.api.update.UpdateApkDialogActivity;
import com.epfresh.api.utils.AppUtils;
import com.epfresh.api.utils.CrashHandler;
import com.epfresh.api.utils.FileUtil;
import com.epfresh.api.utils.L;
import com.epfresh.api.utils.LocalDisplay;
import com.epfresh.api.utils.T;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import com.epfresh.api.constant.*;
import com.tencent.mmkv.MMKV;

/**
 * Created by wzh on 16-6-27.
 */
public class ApplicationHelper {

    public boolean isDownloadApk;
    public static AppApplication mContext;

    public static DocFile docFile;
    public String docFileName = "doc.json";
    public boolean flag_498 = true;


    private static ApplicationHelper instance;

    public static boolean isHomeActivityAlive;
    public static boolean isUpdateActivityAlive;
    public static boolean isHasActivityAlive;
    public static boolean isDownloadApkFail;
    public static UpdateApkDialogActivity updateApkDialogActivity;


    private User user;

    private City city;

    public static int urlChoose = 0;//0代表正常用智慧商户的url  1代表用批发市场的url  2代表用批发市场带tolen的url

    public static void init(AppApplication context) {
        mContext = context;

        if (Constant.DEV) {
            //启用日志
            L.openAll();
        } else {
            //关闭日志
            L.closeAll();
        }
        L.timeMills();
        //初始化toast
        T.init(mContext);
        // 初始化文件
        FileUtil.init(mContext);
        //初始化屏幕换算工具类
        LocalDisplay.init(mContext);
        //初始化网络请求
        RequestManager.getInstance().init(mContext);
        //初始化异常捕获
        CrashHandler.getInstance().init(mContext, null, null, true);
        CrashHandler.getInstance().uploadExceptionToMailAsync();

    }

    public static boolean getDev() {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        boolean isDev = sp.getBoolean("isDev", Constant.isDEV);
        return isDev;
    }

    public static int getEnv() {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        int isDev = sp.getInt("env", Constant.ENV);
        return isDev;
    }

    public static void switchEnv(int env) {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putInt("env", env);
        edit.commit();
        com.epfresh.api.constant.Constant.ENV_CUR = env;
        com.epfresh.api.constant.Constant.init(Constant.isDEV, mContext.getAppDomain());

    }

    public static void switchRp() {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putInt("env", 0);
        edit.commit();
        com.epfresh.api.constant.Constant.ENV_CUR = 0;
        com.epfresh.api.constant.Constant.init(Constant.isDEV, mContext.getAppDomain());
    }

    public static void switchRc() {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putInt("env", 1);
        edit.commit();
        com.epfresh.api.constant.Constant.ENV_CUR = 1;
        com.epfresh.api.constant.Constant.init(Constant.isDEV, mContext.getAppDomain());
    }

    public static void switchBeta() {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putInt("env", 2);
        edit.commit();
        com.epfresh.api.constant.Constant.ENV_CUR = 2;
        com.epfresh.api.constant.Constant.init(Constant.isDEV, mContext.getAppDomain());
    }

    public static void switchDev() {
        SharedPreferences sp = mContext.getSharedPreferences("status", Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putInt("env", 3);
        edit.commit();
        com.epfresh.api.constant.Constant.ENV_CUR = 3;
        com.epfresh.api.constant.Constant.init(Constant.isDEV, mContext.getAppDomain());
    }

    /**
     * 存储最新时间(招代办小红点)
     *
     * @param dotRefreshTime
     */
    public void setDotRefreshTime(long dotRefreshTime) {
        SharedPreferences sharedPreferences = mContext.getSharedPreferences("dot_refresh_time", Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putLong("red_dot_refresh_time", dotRefreshTime);
        editor.commit();
    }

    /**
     * 获取存储的时间(招代办小红点)
     *
     * @return
     */
    public long getDotRefreshTime() {
        SharedPreferences sharedPreferences = mContext.getSharedPreferences("dot_refresh_time", Activity.MODE_PRIVATE);
        return sharedPreferences.getLong("red_dot_refresh_time", 0);
    }

    public static ApplicationHelper getInstance() {
        if (instance == null) {
            synchronized (ApplicationHelper.class) {
                if (instance == null) {
                    instance = new ApplicationHelper();
                }
            }
        }
        return instance;
    }

    public static AppApplication getAppApplication() {
        return mContext;
    }


    public User getUser() {
        if (user == null || user.getTag() == null || "".equals(user.getTag())) {
            SharedPreferences sp = mContext.getSharedPreferences(
                    Constant.USER_INFO_FILE_KEY, Activity.MODE_PRIVATE);
            String userStr = sp.getString(Constant.USER_STR, "");
            if (!"".equals(userStr)) {
                user = User.decryptUser(userStr);
            } else {
                user = new User();
            }
        }
        return user;
    }


    public void expiredTime() {
        if (user != null && user.getAccountId() != null && !"".equals(user.getAccountId())) {
            RequestEntityMap re = new RequestEntityMap();
            re.putParameter("accountId", user.getAccountId());
            re.setCmd(AppRouterConstant.cmd_account_acc_setExpiredTime);
            requestSilent(re, AppRouterConstant.cmd_account_acc_setExpiredTime, null);
        }
    }

    //user不为null
    public void updateUser(User user) {
        this.user = user;
        String encryptUser = user.encryptUser();
        SharedPreferences sp = mContext.getSharedPreferences(
                Constant.USER_INFO_FILE_KEY, Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putString(Constant.USER_STR, encryptUser);
        edit.commit();
    }

    public void clearUser() {
        SharedPreferences sp = mContext.getSharedPreferences(
                Constant.USER_INFO_FILE_KEY, Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.remove(Constant.USER_STR);
        edit.commit();
        user = null;
    }


    public City getCity() {
        if (city == null) {
            SharedPreferences sp = mContext.getSharedPreferences(
                    Constant.USER_INFO_FILE_KEY, Activity.MODE_PRIVATE);
            String userStr = sp.getString(Constant.CITY_STR, "");
            if (!"".equals(userStr)) {
                city = City.decrypt(userStr);
            } else {
                city = new City();
            }
        }
        return city;
    }

    public void updateCity(City city) {
        this.city = city;
        String encryptUser = city.encrypt();
        SharedPreferences sp = mContext.getSharedPreferences(
                Constant.USER_INFO_FILE_KEY, Activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putString(Constant.CITY_STR, encryptUser);
        edit.commit();
    }


    private File getDocFile() {
        File f = new File(FileUtil.getmDataCacheRootPath() + "/" + docFileName);
        Log.e("doc_url", "file:" + f.getPath());
        return f;
    }

    public DocFile getDoc() {
        if (docFile == null) {
            docFile = new DocFile();
            docFile.init();
        }

        return docFile;
    }


    public void updateDocFile() {
        File f = getDocFile();
        if (f.exists()) {
            String s = FileUtil.readInternal(docFileName);
            if (s != null && !"".equals(s)) {
                DocFile docFile = DocFile.decrypt(s);
                if (docFile != null) {
                    this.docFile = docFile;
                }
            }
        }
    }

    //type == 0,采购商
    public void updateVersion(final boolean dialogShow, final AppActivity activity) {
        final RequestEntity requestEntity = new RequestEntity();
        requestEntity.setCmd(AppRouterConstant.cmd_account_acc_update);
        if (dialogShow) {
            activity.showProgressDialog();
        }
        requestSilent(requestEntity, AppRouterConstant.cmd_account_acc_update, true, new OnRequestListener<VersionNew>() {
            @Override
            public VersionNew jsonToObj(String responseStr) {
                VersionNew version = new Gson().fromJson(responseStr, VersionNew.class);
                return version;
            }

            @Override
            public void onFail(int failCode, Object arg, Object tag) {
                if (dialogShow) {
                    activity.hideProgressDialog();
                }
            }

            @Override
            public void onResponseError(int failCode, Object arg, Object tag) {
                if (dialogShow) {
                    activity.hideProgressDialog();
                }
/*                if (failCode == 499) {//用于强制更新
                    requestDownloadUrl(true);
                    Log.e("update", "--------------");
                }*/
            }

            @Override
            public void onStart(Object tag) {
                if (dialogShow) {
                    activity.showProgressDialog();
                }
            }

            @Override
            public void onResponse(ResponseEntity<VersionNew> response, Object tag) {
                if (dialogShow) {
                    activity.hideProgressDialog();
                }
                VersionNew version = response.getResponseElement();
                if (version != null) {
                    update(dialogShow, version.isHasNewVersion(), version.isForce(), version.getUrl());
                }
                if (version != null) {
                    downloadDoc(version);
                }
            }
        });
    }

    private void downloadDoc(final VersionNew v) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    if (v != null) {
                        VersionNew.AllDocumentBean allDocument = v.getAllDocument_version();
                        String serverVersionNew = allDocument.getVersion();

                        if (docFile == null || docFile.isNeedUpdate(serverVersionNew)) {
                            //更新
                            DownloadFile downloadFile = new DownloadFile();
                            //同步下载文件
                            Object o = downloadFile.downloadFile(Constant.URL_DOC, getDocFile(), null);
                            if (o != null && o instanceof File) {
                                updateDocFile();
                            }
                        }
                    }
                } catch (Exception e) {

                }

            }
        }.start();
    }

    public void update(boolean dialogShow, boolean hasNew, boolean force, String url) {
        if (hasNew) {
            if (isHomeActivityAlive && !isUpdateActivityAlive) {
                Intent intent = new Intent(mContext.getApplicationContext(), UpdateApkDialogActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra(Constants.APK_DOWNLOAD_URL, url);
                if (force) {
                    intent.putExtra("isForceUpdate", true);
                } else {
                    intent.putExtra("isForceUpdate", false);
                }
                mContext.startActivity(intent);
            } else {
                showNotification("点击下载更新", url);
            }
        } else if (dialogShow) {
            T.toast("当前已是最新版本");
        }
    }

    public void showNotification(String content, String appUrl) {
        if (isDownloadApk) {
            return;
        }
        Notification noti;
        Intent intent = new Intent(mContext, DownloadService.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(Constants.APK_DOWNLOAD_URL, appUrl);
        PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        int smallIcon = mContext.getApplicationInfo().icon;
        noti = new NotificationCompat.Builder(mContext).setTicker(mContext.getString(R.string.newUpdateAvailable))
                .setContentTitle(mContext.getString(R.string.newUpdateAvailable)).setContentText(content).setSmallIcon(smallIcon)
                .setContentIntent(pendingIntent).build();

        noti.defaults = NotificationCompat.DEFAULT_SOUND;
        noti.flags = android.app.Notification.FLAG_AUTO_CANCEL;
        NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, noti);
    }


    public <T> void requestSilent(Object data, Object tag, OnRequestListener<T> onRequestListener) {
        requestSilent(data, tag, true, onRequestListener);
    }

    public <T> void requestSilent(Object data, Object tag, boolean isAppVersionNew, final OnRequestListener<T> onRequestListener) {

        if (data instanceof RequestEntity) {
            ((RequestEntity) data).setClientIdentifierCode(AppUtils.getUniquePsuedoID());
            //((RequestEntity) data).setToken(getUser().getToken());
            ((RequestEntity) data).setAppDomain(mContext.getAppDomain());
            PackageManager pm = mContext.getPackageManager();
            PackageInfo pi = null;

            String appVersionNew = "";
            try {
                pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
                appVersionNew = pi.versionName;
            } catch (Exception e) {
                e.printStackTrace();
            }

            HashMap<String, Object> map = ((RequestEntity) data).getDeviceInfo();
            if (map == null) {
                map = new HashMap<>();

            }
            map.put("os", "android");
            map.put("osVersion", Build.VERSION.RELEASE);
            map.put("model", Build.MODEL);

            ((RequestEntity) data).setDeviceInfo(map);
            if (isAppVersionNew) {
                ((RequestEntity) data).setAppVersion(appVersionNew);
            } else {
                ((RequestEntity) data).setAppVersion(null);
            }
        }

        String baseUrl;
        if (Constant.APP_DOMAIN_PURCHASER.equals(mContext.getAppDomain())) {
            baseUrl = Constant.host + "/purchase";
        } else {
            if (urlChoose == 0) {
                baseUrl = Constant.host + "/supply";
            } else {
                baseUrl = Constant.host + "/wmmsapp";
            }
        }
        if (urlChoose == 0) {
            //这里还要顺便判断一下是不是登陆的接口，因为登陆不让带着token过去
            if (ApplicationHelper.getInstance().getUser().getAccess_token() != null && !tag.equals("wr-account/account/login")) {
                baseUrl += "?access_token=" + ApplicationHelper.getInstance().getUser().getAccess_token();//todo
            }
        } else if (urlChoose == 2) {
            baseUrl += "?token=" + MMKV.defaultMMKV().decodeString("token");
        }
        Log.e("s_baseUrl", baseUrl);
        HttpRequest request = new HttpRequest(data, baseUrl, new OnRequestListener() {
            @Override
            public Object jsonToObj(String responseStr) {

                if (onRequestListener != null) {
                    return onRequestListener.jsonToObj(responseStr);
                }
                return null;
            }

            @Override
            public void onFail(int failCode, Object arg, Object tag) {
                if (onRequestListener != null) {
                    onRequestListener.onFail(failCode, arg, tag);
                }
            }

            @Override
            public void onResponseError(int failCode, Object arg, Object tag) {
                if (onRequestListener != null) {
                    onRequestListener.onResponseError(failCode, arg, tag);
                }
            }

            @Override
            public void onStart(Object tag) {
                if (onRequestListener != null) {
                    onRequestListener.onStart(tag);
                }
            }

            @Override
            public void onResponse(ResponseEntity response, Object tag) {
                if (onRequestListener != null) {
                    onRequestListener.onResponse(response, tag);
                }
            }
        });

//        if (NetworkUtil.isNetworkAvailable(this)) {
        RetryPolicy retryPolicy = new DefaultRetryPolicy(RequestManager.TIMEOUT_COUNT, RequestManager.RETRY_TIMES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        request.setRetryPolicy(retryPolicy);
        request.setTag(tag);
        RequestManager.getInstance().request(request);
//        } else {
//            requestSilent.onFail(HttpRequest.FAIL_NO_NET, null, tag);
//        }
    }

    public <T> void request(Object data, Object tag, final AppActivity.OnTokenInVain onTokenInVain, final AppActivity.AuthCheck authCheck, final OnRequestListener<T> onRequestListener) {
        requestBuyer(data, null, tag, onTokenInVain, authCheck, onRequestListener);
    }

    public <T> void requestBuyer(Object data, String baseUrl, Object tag, final AppActivity.OnTokenInVain onTokenInVain, final AppActivity.AuthCheck authCheck, final OnRequestListener<T> onRequestListener) {

        if (data instanceof RequestEntity) {
            ((RequestEntity) data).setClientIdentifierCode(AppUtils.getUniquePsuedoID());
            //((RequestEntity) data).setToken(getUser().getToken());
            ((RequestEntity) data).setAppDomain(mContext.getAppDomain());
            PackageManager pm = mContext.getPackageManager();
            PackageInfo pi = null;
            String appVersionNew = "";
            try {
                pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
                appVersionNew = pi.versionName;
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            HashMap<String, Object> map = new HashMap<>();
            map.put("os", "android");
            map.put("osVersion", Build.VERSION.RELEASE);
            map.put("model", Build.MODEL);

            ((RequestEntity) data).setDeviceInfo(map);
            ((RequestEntity) data).setAppVersion(appVersionNew);
        }

        OnRequestListener mOnRequestListener = new OnRequestListener() {
            @Override
            public Object jsonToObj(String responseStr) {

                if (onRequestListener != null) {
                    return onRequestListener.jsonToObj(responseStr);
                }
                return null;
            }

            @Override
            public void onFail(int failCode, Object arg, Object tag) {
                boolean isMain = true;
                boolean isCurrent = true;

                if (tag != null && tag instanceof RequestTag) {
                    RequestTag requestTag = (RequestTag) tag;

                    if (requestTag.type == RequestTag.TYPE_MAIN) {
                        isMain = true;
                        isCurrent = false;
                    } else if (requestTag.type == RequestTag.TYPE_CURRENT) {
                        isMain = false;
                        isCurrent = true;
                    } else if (requestTag.type == RequestTag.TYPE_ALL) {
                        isMain = true;
                        isCurrent = true;
                    }
                }

                if (isCurrent && onRequestListener != null) {
                    onRequestListener.onFail(failCode, arg, tag);
                }
                if (isMain && failCode != HttpRequest.FAIL_NO_NET) {
                    com.epfresh.api.utils.T.toast(ApplicationHelper.getInstance().getDoc().getNetWeak());
                }
            }

            @Override
            public void onResponseError(int failCode, Object arg, Object tag) {
                Log.e("tony", "onResponseError--->>failCode:" + failCode);
                if (failCode == 403 || failCode == 401) {
                    if (onTokenInVain != null)
                        onTokenInVain.onTokenInVain();
                } else if (failCode == 499) {//用于强制更新
                    updateVersion(false, null);
                    //Log.e("update", "--------------");
                } else if (failCode == 498) {
                    if (authCheck != null && flag_498) {
                        authCheck.onAuthCheck();
                        flag_498 = false;
                    }
                }
                if (onRequestListener != null) {

                    boolean isMain = true;
                    boolean isCurrent = true;
                    if (tag != null && tag instanceof RequestTag) {
                        RequestTag requestTag = (RequestTag) tag;

                        if (requestTag.type == RequestTag.TYPE_MAIN) {
                            isMain = true;
                            isCurrent = false;
                        } else if (requestTag.type == RequestTag.TYPE_CURRENT) {
                            isMain = false;
                            isCurrent = true;
                        } else if (requestTag.type == RequestTag.TYPE_ALL) {
                            isMain = true;
                            isCurrent = true;
                        }
                    }

                    if (isCurrent && onRequestListener != null) {
                        onRequestListener.onResponseError(failCode, arg, tag);
                    }
                    if (isMain && failCode != 499) {
                        com.epfresh.api.utils.T.toast("" + arg);
                    }

                }
            }

            @Override
            public void onStart(Object tag) {
                if (onRequestListener != null) {
                    onRequestListener.onStart(tag);
                }
            }

            @Override
            public void onResponse(ResponseEntity response, Object tag) {
                try {
                    if (onRequestListener != null) {
                        onRequestListener.onResponse(response, tag);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        //这里要对baseUrl进行相关的修改
/*        if (baseUrl == null) {
            HttpRequest request = new HttpRequest(data, mOnRequestListener);
            RetryPolicy retryPolicy = new DefaultRetryPolicy(RequestManager.TIMEOUT_COUNT, RequestManager.RETRY_TIMES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            request.setRetryPolicy(retryPolicy);
            request.setTag(tag);
            RequestManager.getInstance().request(request);
        } else {
            //这里还要顺便判断一下是不是登陆的接口，因为登陆不让带着token过去
            if (ApplicationHelper.getInstance().getUser().getAccessToke() != null && !tag.equals("wr-account/account/login")) {
                baseUrl += "?access_token=" + ApplicationHelper.getInstance().getUser().getAccessToke();//todo
            }
            HttpRequest request = new HttpRequest(data, baseUrl, mOnRequestListener);
            RetryPolicy retryPolicy = new DefaultRetryPolicy(RequestManager.TIMEOUT_COUNT, RequestManager.RETRY_TIMES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            request.setRetryPolicy(retryPolicy);
            request.setTag(tag);
            RequestManager.getInstance().request(request);
        }*/
        if (Constant.APP_DOMAIN_PURCHASER.equals(mContext.getAppDomain())) {
            baseUrl = Constant.host + "/purchase";
        } else {
            if (urlChoose == 0) {
                baseUrl = Constant.host + "/supply";
            } else {
                baseUrl = Constant.host + "/wmmsapp";
            }
        }
        if (urlChoose == 0) {
            //这里还要顺便判断一下是不是登陆的接口，因为登陆不让带着token过去
            if (ApplicationHelper.getInstance().getUser().getAccess_token() != null && !tag.equals("wr-account/account/login")) {
                baseUrl += "?access_token=" + ApplicationHelper.getInstance().getUser().getAccess_token();//todo
            }
        } else if (urlChoose == 2) {
            baseUrl += "?token=" + MMKV.defaultMMKV().decodeString("token");
        }
        Log.e("baseUrl", baseUrl);
        HttpRequest request = new HttpRequest(data, baseUrl, mOnRequestListener);
        RetryPolicy retryPolicy = new DefaultRetryPolicy(RequestManager.TIMEOUT_COUNT, RequestManager.RETRY_TIMES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        request.setRetryPolicy(retryPolicy);
        request.setTag(tag);
        RequestManager.getInstance().request(request);
    }


    public String getFileProvider() {
        return getAppApplication().getAppFileProvider();
    }

}
